param(
	[Parameter(Mandatory=$false)]                             
	[string]$inputFile="inputlist.txt",     # the input file to store vdi,domain and fid list
	[Parameter(Mandatory=$false)]                             
	[switch]$inputFileSaved,               # tell if inputfile has been saved, otherwise will popup text to let user enter VDI list.
	[Parameter(Mandatory=$false)]                             
	[switch]$functionInvoked              # tell if script needs to invoke functions
)
$st=get-date
$this_path = Split-Path -Parent ($MyInvocation.MyCommand.Definition) # get the directory of this running script
$parent_path=(get-item $this_path).Parent.FullName
If( !$functionInvoked ){
	. "$parent_path\functions.ps1" # import functions to powershell from functions.ps1
}
If( $inputFile -notlike "*\*"){
    $inputFile="$this_path\$inputFile"
}
$inputlist=Get-Inputlist $inputFile $inputFileSaved
#-----------------------------------------------Software Version Setting Checking--------------------------------------------------------------
$software_temp_path="$this_path\temp" # used to store each result csv file from end vdi incase the script breaks in the middle of running unexpectedly so that we can check the file and know which ones we have already checked
del "$software_temp_path\*.csv" -Force -ErrorAction Ignore
del "$this_path\*.csv" -Force -ErrorAction Ignore
New-FileOrFolder $software_temp_path -d
$software_action={
	param($line,$cnt,$ActionParams)
	#<---------------------------- initilize functions and parameters
	Function Compare-FileRegAndExeVersion(){
		param(
			[Parameter(Mandatory=$True)]
			[AllowNull()]
			[string]$reg_path
		)
		If( !$reg_path ){return "N"}
		$reg_version=$null ; $exe_version=$null
		If( ($reg_detail=reg query $reg_path 2>$null) -ne $null){
			$reg_version=(($reg_detail -imatch "\bDisplayVersion") -split('REG_SZ'))[-1].trim()
			$exe_path="\\$vdi\c$"+(($reg_detail -imatch "\bInstallLocation") -split('C:'))[-1].trim()
			$exe_path=Switch -regex ($exe_path){
				"Automation Anywhere Enterprise"{"$_\Client\Automation Anywhere.exe";break}
				"jre.*\\bin"{"$_\javaws.exe";break}
				"jre.*\\$"{"$_\bin\java.exe"}
			}
			Try{
				$exe_detail=gi $exe_path -ea 1
				$exe_version=$exe_detail.VersionInfo.ProductVersion
				If( $reg_path -imatch 'CB6A8B9C-0E2A-4746-B096-438929F00A15' ){
					$exe_version=Switch ($exe_version){
						"10.2.3.0"{"10.2.0.0";break}
						"10.2.19.0"{"10.3.0.0";break}
						"10.2.19.4"{"10.3.4.0";break}
						"10.2.19.20"{"10.3.5.0";break}
						"10.2.35.0"{"10.5.0.0"}
					}
				}
			}Catch{If( $reg_version ){return "R-$reg_version<-->N-$exe_path"}}Finally{}
		}
		If( $reg_version -and $exe_version ){
			If( $exe_path -imatch "jre.*\\bin" ){
			    $reg_main_version=$reg_version.Substring(2)
			}
			If( $exe_version -inotmatch $reg_main_version){
				return "R-$reg_version<-->P-$exe_version"
			}else{return $reg_version}
		}elseif($reg_version -and !$exe_version){return "R-$reg_version<-->N-PV"
		}elseif(!$reg_version -and $exe_version){return "P-$exe_version<-->N-RV"}
		return "N"
	}
	Function Get-NETVersion($reg,$net_version ){
		Foreach( $r in ((reg query $reg) -imatch '^HKEY_LOCAL_MACHINE')){
			$r=$r -replace("^HKEY_LOCAL_MACHINE","\\$vdi\HKLM")
			If( $r -ne  $reg){
				If( ($rst=(reg query $r /v Version 2>$null) -imatch '\bVersion') -ne $null){
					If( ($version= ($rst -split('REG_SZ'))[-1].trim()) -gt $net_version){
						$net_version=$version
					}
				}else{Get-NETVersion $r}
			}
		}
		return $net_version
	}
	try{$vdi,$domain,$fid,$env=$line.split(",").trim()}catch{}
	$software_temp_path=$ActionParams
	$software_pros = [ordered]@{
		"Category/Setting"="$vdi/$fid/$domain";
		"Software/AAVersion"="N";
		"Software/ChromeVersion"="N";
		"Software/IEVersion"="N"
		"Software/JavaVersion"="N";
		"Software/JWSVersion"="N";
		"Software/NetProbeVersion"="N";
		"Software/NETVersion"="N";
		"Software/PSVersion"="N"
	}
	$reg32_path="\\$vdi\HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
	$reg64_path="\\$vdi\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
	#<---------------------------- start checking software versions
	If(Test-Connection $vdi -quiet -count 1 -ErrorAction Ignore){ # checking if $vdi is online
		write-host "Processing in $cnt-$vdi for software version checking...`n"
		#<----------------------------1 set aa version---------------------------->
		Try{ 
			Get-Service RemoteRegistry -cn $vdi|?{$_.Status -ieq "Stopped"}|Start-Service
			$software_pros.Set_Item("Software/AAVersion",(Compare-FileRegAndExeVersion "$reg32_path\{CB6A8B9C-0E2A-4746-B096-438929F00A15}"))
		}Catch{
		    If($_.exception -like "*Access is denied*"){
				$software_pros.Set_Item("Category/Setting","$vdi/$fid/$domain Access is denied")
			}else{$software_pros.Set_Item("Category/Setting","$vdi/$fid/$domain-error")}
			$rst= New-Object PSObject -Property $software_pros
			Write-Host -ForegroundColor Red $_.exception
			return $rst
		}Finally{}
		#<----------------------------2  set chrome version---------------------------->
		$software_pros.Set_Item("Software/ChromeVersion",(gi "\\$vdi\C$\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ea 0).VersionInfo.ProductVersion)
		#<----------------------------3  set ie version---------------------------->
		$software_pros.Set_Item("Software/IEVersion",((reg query "\\$vdi\HKLM\SOFTWARE\Microsoft\Internet Explorer" /v svcVersion 2>$null)[-2] -split("REG_SZ"))[-1].trim())
		#<----------------------------4  set java version---------------------------->
		If( ($java_reg_path=(reg query $reg32_path|?{$_ -imatch '26A24AE4-039D-4CA4-87B4'}) -replace("^HKEY_LOCAL_MACHINE","\\$vdi\HKLM")) -eq $null){
		    $java_reg_path=(reg query $reg64_path|?{$_ -imatch '26A24AE4-039D-4CA4-87B4'}) -replace("^HKEY_LOCAL_MACHINE","\\$vdi\HKLM")
		}
		$software_pros.Set_Item("Software/JavaVersion",(Compare-FileRegAndExeVersion $java_reg_path))
		#<----------------------------4 set jws version---------------------------->
		If( ($java_version=$software_pros.'Software/JavaVersion') -ine "N" -and $java_reg_path -ne $null){
			$reg_path=Switch -regex ((reg query $java_reg_path 2>$null) -imatch "\bInstallLocation"){
				"\(x86\)"{$reg32_path;break}
				default{$reg64_path}
			}
			$jws_reg_path=Switch -regex ($java_version){
				"7.0.1010" {"$reg_path\{2EDB9CA3-037D-4C4D-8692-BC5A4CFF87C0}";break}
				"7.0.800"  {"$reg_path\{427563F9-23DC-4B3A-A96D-C1EB69A07F71}";break}
				"8.0.910"  {"$reg_path\{91137DFD-1A6E-40C0-A6E9-3605C07920AA}"}
			}
			$software_pros.Set_Item("Software/JWSVersion",(Compare-FileRegAndExeVersion $jws_reg_path))
		}
		#<----------------------------5 set netprobe version---------------------------->
		If( ($netprobe_version=((reg query "$reg32_path\NetprobeNT-7136 GA3.7.1_is1" /v "Inno Setup: Setup Version" 2>$null)[-2] -split("REG_SZ"))[-1].trim()) -ne $null ){$software_pros.Set_Item("Software/NetProbeVersion",$netprobe_version)}
		#<----------------------------6 set .NET version---------------------------->
		$net_version='0'
		Foreach( $reg in ((reg query "\\$vdi\HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP") -imatch '\\v')){
			$reg=$reg -replace("^HKEY_LOCAL_MACHINE","\\$vdi\HKLM")
			If( ($rst=(reg query $reg /v Version 2>$null) -imatch '\bVersion') -ne $null){
				If( ($version= ($rst -split('REG_SZ'))[-1].trim()) -gt $net_version){
					$net_version=$version
				}
			}else{$net_version=Get-NETVersion $reg $net_version}
		}
		$software_pros.Set_Item("Software/NETVersion",$net_version)
		#<----------------------------7 set powershell version---------------------------->
		If( ($ps=(reg query "\\$vdi\HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\" /v PowerShellVersion 2>$null) -imatch "Version\b") -eq $null ){
			$ps=(reg query "\\$vdi\HKLM\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\" /v PowerShellVersion 2>$null) -imatch "Version\b"
		}
		If( ($psversion=($ps -split('REG_SZ'))[-1].trim()) -ne ''){$software_pros.Set_Item("Software/PSVersion",$psversion)}
	}else{
		$software_pros.Set_Item("Category/Setting","$vdi-invalid name or offline/$fid/$domain")
	}
	$rst= New-Object PSObject -Property $software_pros
	Write-Host -ForegroundColor Yellow "----$cnt-$vdi Done check software version info----`n"
	$rst|Export-Csv -Path "$software_temp_path\$vdi-software.csv" -UseCulture -NoTypeInformation -Encoding UTF8 -Force -ErrorAction Ignore
	return $rst
}
$softwares = Start-BulkThreads $inputlist $software_action $software_temp_path -maxCnt 100|sort "Category/Setting"
Export-Result $softwares "software versions" "$this_path\software.csv" ([math]::Round(((get-date)-$st).totalseconds))
